package com.ybt.heartratem.common.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Environment;
import android.text.TextUtils;

import com.ybt.heartratem.common.app.CacheManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 文件帮助类
 *
 * @author tony.liu
 */
public class FileUtil {

    private static final String TAG = FileUtil.class.getCanonicalName();

    /**
     * 判断是否有SDCard
     *
     * @return 有为true，没有为false
     */
    public static boolean hasSDCard() {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            return true;
        }
        return false;
    }

    /**
     * 获取文件名
     *
     * @param str url或文件路径
     * @return
     */
    public static String getFileName(String str) {
        String filename = null;
        try {
            if (!TextUtils.isEmpty(str)) {
                if (str.contains("?")) {
                    String[] strAry = str.split("\\?");
                    if (!TextUtils.isEmpty(strAry[0])) {
                        String subFilename = strAry[0].substring(strAry[0].lastIndexOf("/") + 1);
                        String name = subFilename.substring(0, subFilename.indexOf("."));
                        String suffix = subFilename.substring(subFilename.indexOf(".") + 1);
                        String w = str.substring(str.lastIndexOf("/") + 1);
                        filename = name + "-" + w + "." + suffix;
                    }

                } else {
                    filename = str.replaceAll("/", "").replace(":", "");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return filename;
    }


    public static void mkdirs(File file) {
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 删除文件
     *
     * @param filePath
     * @return
     */
    public static boolean deleteFile(String filePath) {
        if (!TextUtils.isEmpty(filePath)) {
            File file = new File(filePath);
            if (file != null && file.exists()) {
                file.delete();
                return true;
            }
        }
        return false;
    }


    /**
     * 根据类型生成文件路径
     *
     * @param type 文件类型 | 见ImageType.TYPE_
     * @return
     */
    public static String createFilePathByType(String type, String oldpath) {
        return createFileDirByType(type) + File.separator + getFileName(oldpath);
    }

    /**
     * 根据类型生成文件目录
     *
     * @param type 文件类型 | 见ImageType.TYPE_
     * @return
     */
    public static String createFileDirByType(String type) {
        String path = CacheManager.SD_IMAGE_DIR + File.separator + type;
        FileUtil.mkdirs(new File(path));
        return path;
    }

    /**
     * 文件压缩保存
     *
     * @param type     文件类型 | 见ImageType.TYPE_
     * @param filepath 文件路径
     * @return
     */
    public static String imageCompressionSave(String type, String filepath) {
        String newFilePath = createFilePathByType(type, filepath);
        File file = new File(filepath);
        if (file.exists()) {
            long fileLength = file.length();
            // 小于100K
            if (fileLength <= 100 * 1024) {
                if (!filepath.equals(newFilePath)) {
                    copyFile(filepath, newFilePath);
                }
            } else {
                String notExists = "";
                FileOutputStream fOut = null;
                try {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 1;
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeFile(filepath, options);
                    // 480 * 800
                    options.inSampleSize = computeSampleSize(options, 480, 800);
                    options.inJustDecodeBounds = false;
                    options.inDither = false;
                    options.inPurgeable = true;
                    options.inInputShareable = true;
                    options.inPreferredConfig = Bitmap.Config.RGB_565;
                    Bitmap sourceBitmap = BitmapFactory.decodeFile(filepath, options);
                    int angle = readPictureDegree(filepath);
                    Matrix matrix = new Matrix();
                    if (angle > 0) {
                        matrix.postRotate(angle);
                        sourceBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);
                    }
                    File newFile = new File(newFilePath);
                    if (null != sourceBitmap) {
                        fOut = new FileOutputStream(newFile);
                        sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 60, fOut);
                        fOut.flush();
                        sourceBitmap.recycle();
                    } else {
                        return notExists;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return notExists;
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                } finally {
                    if (null != fOut) {
                        try {
                            fOut.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                            return notExists;
                        }
                    }
                }
            }
        }
        return newFilePath;
    }

    public static String imageCompressionSave(String filepath) {
        File file = new File(filepath);
        if (file.exists()) {
            long fileLength = file.length();
            // 小于100K
            if (fileLength <= 100 * 1024) {

            } else {
                String notExists = "";
                FileOutputStream fOut = null;
                try {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 1;
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeFile(filepath, options);
                    // 480 * 800
                    options.inSampleSize = computeSampleSize(options, 480, 800);
                    options.inJustDecodeBounds = false;
                    options.inDither = false;
                    options.inPurgeable = true;
                    options.inInputShareable = true;
                    options.inPreferredConfig = Bitmap.Config.RGB_565;
                    Bitmap sourceBitmap = BitmapFactory.decodeFile(filepath, options);
                    int angle = readPictureDegree(filepath);
                    Matrix matrix = new Matrix();
                    if (angle > 0) {
                        matrix.postRotate(angle);
                        sourceBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);
                    }
                    File newFile = new File(filepath);
                    if (null != sourceBitmap) {
                        fOut = new FileOutputStream(newFile);
                        sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 60, fOut);
                        fOut.flush();
                        sourceBitmap.recycle();
                    } else {
                        return notExists;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return notExists;
                } catch (OutOfMemoryError e) {
                    e.printStackTrace();
                } finally {
                    if (null != fOut) {
                        try {
                            fOut.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                            return notExists;
                        }
                    }
                }
            }
        }
        return filepath;
    }

    /**
     * 读取图片属性：旋转的角度
     *
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }


    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) {                                    // 文件存在时
                InputStream inStream = new FileInputStream(oldPath);    // 读入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1024];
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread;                                // 字节数 文件大小
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取压缩比例
     *
     * @param options
     * @param targeW
     * @param targeH
     * @return
     */
    private static int computeSampleSize(BitmapFactory.Options options, int targeW, int targeH) {
        int w = options.outWidth;
        int h = options.outHeight;
        float candidateW = w / targeW;
        float candidateH = h / targeH;

        float candidate = Math.max(candidateW, candidateH);
        if (candidate == 0) {
            return 1;
        }
        if (candidate > 1) {
            if ((w > targeW) && (w / candidate) < targeW) {
                candidate -= 1;
            }
        }

        if (candidate > 1) {
            if ((h > targeH) && (h / candidate) < targeH) {
                candidate -= 1;
            }
        }

        return (int) candidate;
    }

    /**
     * 写入文件内容
     *
     * @param str      需要写入的内容
     * @param savePath 文件路径
     * @return
     */
    public static boolean saveFileByString(String str, String savePath) {
        boolean flag = false;
        if (null != str) {
            FileOutputStream o = null;
            try {
                File file = new File(savePath);
                if (file.exists()) {
                    file.delete();
                }
                o = new FileOutputStream(file);
                o.write(str.getBytes("UTF-8"));
                o.close();
                flag = true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
            return flag;
        }
        return flag;
    }

    /**
     * 删除目录（文件夹）以及目录下的文件
     *
     * @param filePath 被删除目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String filePath) {
        // 如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!filePath.endsWith(File.separator)) {
            filePath = filePath + File.separator;
        }
        File dirFile = new File(filePath);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            } // 删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }

        // 删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    private static int mDirSize = 0;

    /**
     * 获取文件夹大小
     *
     * @param path
     * @return
     */
    public static long getDirSize(String path) {
        mDirSize = 0;

        get_dir_size(new File(path));

        return mDirSize;
    }

    /*
     *
     * @param path
     */
    private static void get_dir_size(File path) {
        File[] list = path.listFiles();
        int len;

        if (list != null) {
            len = list.length;

            for (int i = 0; i < len; i++) {
                try {
                    if (list[i].isFile() && list[i].canRead()) {
                        mDirSize += list[i].length();

                    } else if (list[i].isDirectory() && list[i].canRead() && !isSymlink(list[i])) {
                        get_dir_size(list[i]);
                    }
                } catch (IOException e) {
                }
            }
        }
    }

    private static boolean isSymlink(File file) throws IOException {
        File fileInCanonicalDir = null;
        if (file.getParent() == null) {
            fileInCanonicalDir = file;
        } else {
            File canonicalDir = file.getParentFile().getCanonicalFile();
            fileInCanonicalDir = new File(canonicalDir, file.getName());
        }
        return !fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile());
    }

    /**
     * 删除早期的文件
     *
     * @param dir
     */
    private static void deleteOldestFile(File dir) {
        File[] files = dir.listFiles();
        List<File> filesList = new ArrayList<File>();
        List<File> dirsList = new ArrayList<File>();

        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (file.isDirectory()) {
                dirsList.add(file);
            } else if (file.isFile()) {
                filesList.add(file);
            }
        }

        Collections.sort(filesList, new Comparator<File>() {
            @Override
            public int compare(File f1, File f2) {
                return Long.valueOf(f1.lastModified())
                        .compareTo(f2.lastModified());
            }
        });

        int sonFileSize = filesList.size();
        for (int i = 0; i < sonFileSize / 2; i++) {
            File file = filesList.get(i);
            file.delete();
        }

        for (int i = 0; i < dirsList.size(); i++) {
            deleteOldestFile(dirsList.get(i));
        }

    }

    /**
     * moon dir
     *
     * @param dirFile
     */
    public static void deleteDirFiles(File dirFile) {
        if (dirFile != null && dirFile.exists()) {
            File[] files = dirFile.listFiles();
            for (int i = 0; i < files.length; i++) {
                File file = files[i];
                deleteOldestFile(file);
            }
        }
    }

    /***
     * 删除指定目录的文件
     * @param filePath
     */
    public static void delFileByPath(String filePath) {
        File dirFile = new File(filePath);
        if (dirFile != null && dirFile.exists()) {
            File[] files = dirFile.listFiles();
            if (files != null && files.length > 0) {
                for (int i = 0; i < files.length; i++) {
                    File file = files[i];
                    if (file != null && file.exists()) {
                        file.delete();
                    }
                }
            }
        }
    }
}
